﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CLM.Gestao.Interfaces;
using CLM.Gestao.Administrador.DAL;

namespace CLM.Gestao.Administrador.BLL
{
    public class PeriodoAno : PeriodoAnoBLO<TB_PERIODO_ANO>
    {
        #region Propriedades

        public int IdPeriodoAno { get; set; }
        public string AnoExercicio { get; set; }
        public bool? IndicaExercicioFechado { get; set; }
        public List<Periodo> Periodos { get; set; }

        #endregion Propriedades

        #region Conversões

        private List<TB_PERIODO_ANO> ConvertToEDM(List<Lista> pLista)
        {
            List<TB_PERIODO_ANO> List = (from l in pLista
                                     select new TB_PERIODO_ANO
                                     {
                                         ID_PERIODO_ANO = l.IdPeriodoAno,
                                         INDICA_EXERCICIO_FECHADO = l.IndicaPeriodoAnoFechado,
                                         ANO_EXERCICIO = l.AnoPeriodo
                                     }).ToList();
            return List;
        }

        private List<Lista> ConvertToContext(IQueryable<TB_PERIODO_ANO> pContext)
        {
            List<Lista> List = (from l in pContext
                                select new Lista
                                {
                                    IdPeriodoAno = l.ID_PERIODO_ANO,
                                    IndicaPeriodoAnoFechado = l.INDICA_EXERCICIO_FECHADO,
                                    AnoPeriodo = l.ANO_EXERCICIO
                                }).ToList();
            return List;
        }

        #endregion Conversões

        #region CRUD

        public void Add(List<Lista> pLista)
        {
            try
            {
                foreach (var item in ConvertToEDM(pLista))
                    base.Add(item);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public void Delete(List<Lista> pLista)
        {
            try
            {
                foreach (var item in ConvertToEDM(pLista))
                    base.Delete(item);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public void Update(List<Lista> pLista)
        {
            try
            {
                foreach (var item in ConvertToEDM(pLista))
                    base.Update(item);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        private IQueryable<TB_PERIODO_ANO> Get(Lista pPesquisa)
        {
            IQueryable<TB_PERIODO_ANO> Consulta;

            Consulta = from p in GetAll()
                       select p;

            if (pPesquisa != null)
            {
                if (pPesquisa.AnoPeriodo != null)
                    Consulta = from p in Consulta where p.ANO_EXERCICIO == pPesquisa.AnoPeriodo select p;

                if (pPesquisa.IdPeriodoAno > 0)
                    Consulta = from p in Consulta where p.ID_PERIODO_ANO == pPesquisa.IdPeriodoAno select p;

                if (pPesquisa.IndicaPeriodoAnoFechado != null)
                    Consulta = from p in Consulta where p.INDICA_EXERCICIO_FECHADO == pPesquisa.IndicaPeriodoAnoFechado select p;
            }
            return Consulta;
        }

        #endregion CRUD

        #region Retorna Listas e Itens

        public List<Lista> GetLista()
        {
            return GetLista(new Lista());
        }

        public List<Lista> GetLista(Lista pPesquisa)
        {
            var ListaUsuario = ConvertToContext(Get(pPesquisa));
            return ListaUsuario;
        }

        #endregion Retorna Listas e Itens

        #region Consultas

        public List<PeriodoAno> RecuperaPeriodosAno()
        {
            List<PeriodoAno> ListaExercicios = (from l in ((from l in Get(new Lista())
                                             select l).OrderBy(o => o.ANO_EXERCICIO))
                                               select new PeriodoAno
                                               {
                                                   IdPeriodoAno = l.ID_PERIODO_ANO,
                                                   IndicaExercicioFechado = l.INDICA_EXERCICIO_FECHADO,
                                                   AnoExercicio = l.ANO_EXERCICIO
                                               }).ToList();
            return ListaExercicios;
        }

        
        public int UltimoPeriodoAnoCadastrado()
        {
            return (from l in Get(new Lista()).ToList()
                    select int.Parse(l.ANO_EXERCICIO)).Max();
        }

        #endregion Consultas

        #region Processos

        public void NovoPeriodoAno(int pAnoPeriodo)
        {
            this.Add(new TB_PERIODO_ANO()
                    {
                        ANO_EXERCICIO = pAnoPeriodo.ToString(),
                        INDICA_EXERCICIO_FECHADO = false,
                        TB_PERIODO = new TrackableCollection<TB_PERIODO> 
                        { 
                            new TB_PERIODO { MES_PERIODO = 1, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Janeiro" },
                            new TB_PERIODO { MES_PERIODO = 2, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Fevereiro" },
                            new TB_PERIODO { MES_PERIODO = 3, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Março" },
                            new TB_PERIODO { MES_PERIODO = 4, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Abril" },
                            new TB_PERIODO { MES_PERIODO = 5, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Maio" },
                            new TB_PERIODO { MES_PERIODO = 6, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Junho" },
                            new TB_PERIODO { MES_PERIODO = 7, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Julho" },
                            new TB_PERIODO { MES_PERIODO = 8, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Agosto" },
                            new TB_PERIODO { MES_PERIODO = 9, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Setembro" },
                            new TB_PERIODO { MES_PERIODO = 10, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Outubro" },
                            new TB_PERIODO { MES_PERIODO = 11, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Novembro" },
                            new TB_PERIODO { MES_PERIODO = 12, INDICA_PERIODO_FECHADO = false, ANO_PERIODO = pAnoPeriodo, DESCRICAO_PERIODO = "Dezembro"}
                        }
                    }); 
        }

        #endregion

        #region Classes

        /// <summary>
        /// Lista com as propriedades da classe
        /// </summary>
        public class Lista
        {
            public int IdPeriodoAno { get; set; }
            public string AnoPeriodo { get; set; }
            public bool? IndicaPeriodoAnoFechado { get; set; }
        }

        #endregion

    }

    public class PeriodoAnoBLO<T> : IBLO<T> where T : TB_PERIODO_ANO
    {
        private PeriodoAnoDAO<T> _base = new PeriodoAnoDAO<T>();

        public T Add(T pEntity)
        {
            Validate(pEntity);
            _base.Add(pEntity);
            return _base.Save(pEntity);

        }

        public T Save(T pEntity)
        {
            Validate(pEntity);
            return _base.Save(pEntity);

        }

        public void Delete(T pEntity)
        {
            _base.Delete(pEntity);
            _base.Save(pEntity);

        }

        public T Update(T pEntity)
        {
            Validate(pEntity);
            _base.Update(pEntity);
            return _base.Save(pEntity);
        }

        public IQueryable<T> GetAll()
        {
            return _base.GetAll();
        }

        public void Validate(T pEntity)
        {

        }

    }

}
